#ifndef _FMVC_TEMPLATE_READER_
#define _FMVC_TEMPLATE_READER_

#include <fstream>
#include <iostream>
#include <sstream>

#include <boost/regex.hpp>
#include <boost/unordered_map.hpp>


class TemplateReader
{
  typedef boost::unordered_map<std::string,std::string> map;
  class FormatClass
  {
    TemplateReader* _reader;
    map _map;
    public:
    FormatClass(TemplateReader* reader) { _reader = reader; }
    FormatClass(TemplateReader* reader,const map& lmap) : _map(lmap) { _reader = reader; }
    std::string operator()(boost::smatch const &what) 
    { 
      if ( what[1].str() == "t")
      {
        return _reader->ReadTemplate(what[2].str());
      }
      else if ( what[1].str() == "v")
      {
        return _map[what[1].str()]; 
      }
      return "";
    }
  };

  FormatClass fc;

  std::string _templateDirectory;

  public:

  static std::string ReadFile(const std::string& path)
  {
    std::ifstream fileStream(path.c_str(),std::ios::binary);
    std::string fileContent;

    int fileLength;
    fileStream.seekg(0,std::ios::end);
    fileLength = fileStream.tellg();
    fileStream.seekg(0,std::ios::beg);

    if ( fileLength == -1 )
      return "";

    fileContent.reserve(fileLength);
    fileContent.assign((std::istreambuf_iterator<char>(fileStream)),std::istreambuf_iterator<char>());
    return fileContent;
  }


  TemplateReader() : fc(this), _templateDirectory("templates/") {}
  TemplateReader(const map& lmap) : fc(this,lmap),_templateDirectory("templates/") {}

  std::string ReadTemplate(const std::string& templateName)
  {
    std::string fullPath(_templateDirectory);
    fullPath.append(templateName);
    std::string rawContent = ReadFile(fullPath);

    boost::regex r("\\[(.)\\.(\\w+)\\]");
    return boost::regex_replace(rawContent,r,fc);
  }

};

#endif
